import React from 'react';
import dva, { connect } from 'dva';
import {HashRouter,Switch,Route,Link,routerRedux} from 'dva/router';//react-router-dom V5 
import keymaster from 'keymaster';
//routerRedux 来自于react-router-redux 废弃了 => redux-first-history push
//React-router-dom V5中可以直接使用Route Route可以在Switch里
//React-router-dom V6中需要把Route放在Routes里。没有Switch
const app = dva();
//let state = {counter:{number:0}}
app.model({
	namespace: 'counter1',//当前model的名称，这个名称也会成为状态树中的属性
	state: { number: 0 },//当前模型中保存的状态，数据保存在这里
	reducers: {//action处理器，处理同步动作，用来计算最新的state状态
		add(state, action) {
			return { number: state.number + 1 }
		},
		setState(state,action){
			return {number:action.payload}
		}
	},//effects可以处理异步操作和业务逻辑，内部可以使用yield调用其它的effect,比如发请求，派发动作
	effects:{
		//action 动作 effects sagaEffects  redux-saga/effects
		*asyncAdd(action,{put}){
			console.log('effects asyncAdd')
			yield delay(1000);
			//counter/add should not be prefixed with namespace counter
			yield put({type:'add'});
		},
		*goto(action,{put}){
			//解构action获取到payload,payload就是要跳转的路径
			const {payload}=action;// /counter2
			//派发一个动作，通过push方法这个actionCreator创建动作对象
			yield put(routerRedux.push(payload));
		}
	},
	subscriptions:{
		//在系统启动的时候调用接口返回数据，初始化model中的state
		fetchData({dispatch,history}){
			fetch('http://127.0.0.1:8080/data.json')
			.then(res=>res.json())
			.then(res=>{
				console.log(res)
				dispatch({type:'setState',payload:res.initialState});
			})
		},
		KeyboardWatcher({dispatch,history}){
			//监听a这个按键，当用户按下a的时候执行回调
			keymaster('a',()=>dispatch({type:'add'}));
		},
		//监听 路径的变化 ，当路径变化后执行回调，把页面的标题改掉
		locationWatcher({dispatch,history}){
			//通过history的listen方法监听路径变化
			history.listen((location)=>{
				//当路径发生变化时变执行回调，在回调里修改页面的标题
				document.title = location.pathname;
			});
		}
	}
});
app.model({
	namespace: 'counter2',//当前model的名称，这个名称也会成为状态树中的属性
	state: { number: 0 },//当前模型中保存的状态，数据保存在这里
	reducers: {//action处理器，处理同步动作，用来计算最新的state状态
		add(state, action) {
			return { number: state.number + 1 }
		}
	},//effects可以处理异步操作和业务逻辑，内部可以使用yield调用其它的effect,比如发请求，派发动作
	effects:{
		//action 动作 effects sagaEffects  redux-saga/effects
		*asyncAdd(action,{put}){
			console.log('effects asyncAdd')
			yield delay(1000);
			//counter/add should not be prefixed with namespace counter
			yield put({type:'add'});
		}
	}
});
function Counter1({ number, dispatch }) {
	return (
		<div>
			<p>{number}</p>
			<button onClick={() => dispatch({ type: 'counter1/add' })}>+</button>
			<button onClick={() => dispatch({ type: 'counter1/asyncAdd' })}>异步加1</button>
			<button onClick={() => dispatch({ type: 'counter1/goto',payload:'/counter2' })}>跳到/counter2</button>
		</div>
	)
}
const ConnectedCounter1 = connect(
	state => state.counter1//读仓库的状态
	//这里可以传2个参数，actionCreators,如果没有传的话
)(Counter1);
function Counter2({ number, dispatch }) {
	return (
		<div>
			<p>{number}</p>
			<button onClick={() => dispatch({ type: 'counter2/add' })}>+</button>
			<button onClick={() => dispatch({ type: 'counter2/asyncAdd' })}>异步加1</button>
		</div>
	)
}
const ConnectedCounter2 = connect(
	state => state.counter2//读仓库的状态
	//这里可以传2个参数，actionCreators,如果没有传的话
)(Counter2);
//定义路由函数，最终会渲染函数的返回值，也就是虚拟DOM
app.router(()=>(
	<HashRouter>
		<>
		  <ul>
			<li><Link to="/counter1">counter1</Link></li>
			<li><Link to="/counter2">counter2</Link></li>
		  </ul>
		  <Switch>
			<Route path="/counter1" component={ConnectedCounter1}/>
			<Route path="/counter2" component={ConnectedCounter2}/>
		  </Switch>
		</>
	</HashRouter>
));
//在root上启动渲染
app.start('#root');//document.querySelector('#root')

function delay(ms){
	return new Promise((resolve)=>{
		setTimeout(resolve,ms);
	});
}
//在dva中可以使用router定义路由
/**
 * V5 <Route path="/counter1" component={ConnectedCounter1}/>
 * V6 <Route path="/counter1" element={<ConnectedCounter1/>}/>
 * V5 <Switch> 只会渲染第一个匹配的路由
 * V6 <Routes/>
 */